package com.aps.server.kpi;

import com.alibaba.fastjson2.JSON;
import com.aps.algorithm.entity.ApsKpiTemplate;
import com.aps.algorithm.entity.BasicEquipSchedulingResult;
import com.aps.algorithm.kpi.template.DefaultApsKpiTemplateEngine;
import com.aps.common.boot.CoreApplicationContext;
import com.aps.common.model.genetic.ProcessInterval;
import com.aps.server.entity.ApsOperation;
import com.aps.server.entity.ApsOrder;
import com.aps.server.entity.BasicEquip;
import com.aps.server.entity.BasicProduct;
import com.aps.server.kpi.service.EquipKpiCalculatedService;
import com.aps.server.kpi.service.OrderKpiCalculatedService;
import com.aps.server.mapper.ApsOperationMapper;
import com.aps.server.mapper.ApsOrderMapper;
import com.aps.server.mapper.BasicEquipMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author nbZhuozh
 * @Date 2025-11-10  18:25
 **/
@Service
@Slf4j
public class GenericDefaultKpiTemplateEngine extends DefaultApsKpiTemplateEngine {

    @Resource
    OrderKpiCalculatedService orderKpiCalculatedService;
    @Resource
    EquipKpiCalculatedService equipKpiCalculatedService;

    //计算指标：设备标准工时利用率
    public static final String SERVICE_EQUIPMENT_PRODUCE_ABILITY = "service_equipment_produce_ability";
    //计算指标： 各设备标准工时利用率
    public static final String SERVICE_EQUIPMENT_EACH_PRODUCE_ABILITY = "service_equipment_each_produce_ability";
    //计算指标：平均交期履约率计算 （当前配置中所有订单 交期平均率）
    public static final String SERVICE_ORDER_DELIVERY_RATE = "order_delivery_rate";
    //计算指标：每个交期履约率
    public static final String SERVICE_ORDER_EACH_DELIVERY_RATE = "order_each_delivery_rate";
    //基于 ：
    @Override
    public Map<String, Object> applay(List<BasicEquipSchedulingResult> data, List<ApsKpiTemplate> templates){
        //通用 计算出的结果
        Map<String, Object> coreReusltMap = super.applay(data, templates);
        //构造业务参照表
        KpiBizReference reference = KpiBizReference.build(data);
        coreReusltMap.putAll(apply(templates,reference));
        return coreReusltMap;
    }

    private Map<String, Object> apply(List<ApsKpiTemplate> definitions ,KpiBizReference reference) {
        Map<String, Object> coreReusltMap = new HashMap<>();
        for (ApsKpiTemplate definition : definitions) {
            if (definition == null || !StringUtils.equals(definition.getEnabled(),"1") || StringUtils.isBlank(definition.getTemplateCode())) {
                return new HashMap<>();
            }
            switch (definition.getTemplateCode()) {
                //当前配置下 订单履约率 （已选择订单整体的履约率） BigDecimal
                case SERVICE_ORDER_DELIVERY_RATE ->
                        coreReusltMap.put(definition.getTemplateCode(), orderKpiCalculatedService.calAvgOrderDeliveryRate(reference));
                //当前配置下 订单履约率 （已选择订单整体的履约率）Map<String,BigDecimal>
                case SERVICE_ORDER_EACH_DELIVERY_RATE ->
                        coreReusltMap.put(definition.getTemplateCode(), orderKpiCalculatedService.calOrderDeliveryRate(reference));
                case SERVICE_EQUIPMENT_PRODUCE_ABILITY ->
                        coreReusltMap.put(definition.getTemplateCode(), equipKpiCalculatedService.calAvgEquipmentCapacityRate(reference));
                case SERVICE_EQUIPMENT_EACH_PRODUCE_ABILITY ->
                        coreReusltMap.put(definition.getTemplateCode(), equipKpiCalculatedService.calEquipmentCapacityRate(reference));

                default -> log.info("默认模板暂未实现指标计算: {}", definition.getTemplateCode());
            }
        }
        return coreReusltMap;
    }

    //业务参照数据
    @Data
    @Builder
    public static class KpiBizReference{
        //设备信息
        private Map<String, BasicEquip> basicEquipMap;
        //订单信息
        private Map<String , ApsOrder> basicOrderMap;
        //工艺信息
        private Map<String, BasicConstraints> basicConstraintsMap;
        //工序信息
        private Map<String, ApsOperation> basicOperationMap;
        //产品信息
        private Map<String , BasicProduct> basicProductMap;
        //结果数据
        private List<BasicEquipSchedulingResult> basicEquipSchedulingResultList;

        public static KpiBizReference build(List<BasicEquipSchedulingResult> basicEquipSchedulingResultList){
            Set<String> orderIds = new HashSet();
            Set<String> equipmentIds = new HashSet();
            Set<String> operationIds = new HashSet();
            KpiBizReferenceBuilder builder = KpiBizReference.builder();
            builder.basicEquipSchedulingResultList(basicEquipSchedulingResultList);
            //获取所有订单数据
            for (BasicEquipSchedulingResult r : basicEquipSchedulingResultList) {
                orderIds.add(r.getOrderId());
                equipmentIds.add(r.getEquipId());
                operationIds.add(r.getProcessId());
            }
            //订单数据
            if(!CollectionUtils.isEmpty(orderIds)){
                ApsOrderMapper apsOrderMapper = CoreApplicationContext.getApplicationContext().getBean(ApsOrderMapper.class);
                LambdaQueryWrapper<ApsOrder> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(ApsOrder::getId, orderIds);
                List<ApsOrder> orders = apsOrderMapper.selectList(queryWrapper);
                if(!CollectionUtils.isEmpty(orders)){
                    Map<String, ApsOrder> collect = orders.stream().collect(
                            Collectors.toMap(ApsOrder::getId, Function.identity(), (o, n) -> n));
                    builder.basicOrderMap(collect);
                }
            }
            //设备数据
            if(!CollectionUtils.isEmpty(equipmentIds)){
                BasicEquipMapper basicEquipMapper = CoreApplicationContext.getApplicationContext().getBean(BasicEquipMapper.class);
                LambdaQueryWrapper<BasicEquip> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(BasicEquip::getId, equipmentIds);
                List<BasicEquip> basicEquips = basicEquipMapper.selectList(queryWrapper);
                if(!CollectionUtils.isEmpty(basicEquips)){
                    Map<String, BasicEquip> collect = basicEquips.stream().collect(
                            Collectors.toMap(BasicEquip::getId, Function.identity(), (o, n) -> n));
                    builder.basicEquipMap(collect);
                }
            }
            //工序数据
            if(!CollectionUtils.isEmpty(operationIds)){
                ApsOperationMapper operationMapper = CoreApplicationContext.getApplicationContext().getBean(ApsOperationMapper.class);
                LambdaQueryWrapper<ApsOperation> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(ApsOperation::getId, equipmentIds);
                List<ApsOperation> operations = operationMapper.selectList(queryWrapper);
                if(!CollectionUtils.isEmpty(operations)){
                    Map<String, ApsOperation> collect = operations.stream().collect(
                            Collectors.toMap(ApsOperation::getId, Function.identity(), (o, n) -> n));
                    builder.basicOperationMap(collect);
                }
            }
            return builder.build();
        }


    }

    public static List<ProcessInterval> parseProcessIntervalsDetails(String jsonStr){
        if(StringUtils.isEmpty(jsonStr)){
            return Collections.emptyList();
        }
        return JSON.parseArray(jsonStr, ProcessInterval.class);
    }


}
